package com.xuexiang.xuidemo.page.text;

import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AbsButton;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentState;
import ohos.agp.components.Image;
import ohos.agp.components.RadioButton;
import ohos.agp.components.RadioContainer;
import ohos.agp.components.Slider;
import ohos.agp.components.Switch;
import ohos.agp.components.Text;
import ohos.agp.components.TextField;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;

import com.xuexiang.xui_lib.component.edittext.materialedittext.validation.TextUtils;
import com.xuexiang.xui_lib.component.textview.badge.Badge;
import com.xuexiang.xui_lib.component.textview.badge.BadgeView;
import com.xuexiang.xui_lib.util.ColorUtils;
import com.xuexiang.xuidemo.ResourceTable;
import com.xuexiang.xuidemo.page.base.BasePageAbilitySlice;
import com.xuexiang.xuidemo.page.base.Page;
import com.xuexiang.xuidemo.widget.SelectorColorDialog;

import java.util.ArrayList;
import java.util.List;

/**
 * BadgeView角标组件功能示例
 *
 * @since 2021-04-06
 */
@Page(name = "BadgeView", subTitle = "小红点标记",
    action = "BadgeViewAbilitySlice", ability = TextAbility.class)
public class BadgeViewAbilitySlice extends BasePageAbilitySlice
    implements AbsButton.CheckedStateChangedListener, Component.ClickedListener {
    private RadioContainer radioContainer;
    private Text text;
    private Image image, imgBadgeColor, imgTextColor;
    private Button button, btnAnimation;
    private List<Badge> mBadges;
    private List<RadioButton> radioButtons = new ArrayList<>();
    private AbsButton lastRadioButton;
    private Text tvOffsetX, tvOffsetY, tvPadding, tvNumberSize, tvDragState;
    private Slider seekBarOffsetX, seekBarOffsetY, seekBarPadding, seekBarNumberSize;
    private TextField etBadgeNumber, etBadgeText;
    private Switch switchExact, switchShadow, switchDraggable;
    private AbsButton.CheckedStateChangedListener onCheckedChangeListener =
        new AbsButton.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(AbsButton buttonView, boolean isChecked) {
                for (Badge badge : mBadges) {
                    if (buttonView == switchExact) {
                        badge.setExactMode(isChecked);
                    } else if (buttonView == switchDraggable) {
                        badge.setOnDragStateChangedListener(isChecked ? (dragState, badge1, targetView) -> {
                            switch (dragState) {
                                case Badge.OnDragStateChangedListener.STATE_START:
                                    tvDragState.setText("STATE_START");
                                    break;
                                case Badge.OnDragStateChangedListener.STATE_DRAGGING:
                                    tvDragState.setText("STATE_DRAGGING");
                                    break;
                                case Badge.OnDragStateChangedListener.STATE_DRAGGING_OUT_OF_RANGE:
                                    tvDragState.setText("STATE_DRAGGING_OUT_OF_RANGE");
                                    break;
                                case Badge.OnDragStateChangedListener.STATE_SUCCEED:
                                    tvDragState.setText("STATE_SUCCEED");
                                    break;
                                case Badge.OnDragStateChangedListener.STATE_CANCELED:
                                    tvDragState.setText("STATE_CANCELED");
                                    break;
                                default:
                                    break;
                            }
                        } : null);
                    } else if (buttonView == switchShadow) {
                        badge.setShowShadow(isChecked);
                    }
                }
            }
        };

    @Override
    protected int getLayoutId() {
        return ResourceTable.Layout_slice_badge_view;
    }

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        initView();
        setUpView();
        initBadge();
    }

    private void initView() {
        text = (Text) findComponentById(ResourceTable.Id_slice_badge_text);
        image = (Image) findComponentById(ResourceTable.Id_slice_badge_image);
        button = (Button) findComponentById(ResourceTable.Id_slice_badge_button);
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_1));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_2));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_3));
        lastRadioButton = findCastComponentById(ResourceTable.Id_slice_badge_radio_button_3);
        lastRadioButton.setChecked(true);
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_4));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_5));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_6));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_7));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_8));
        radioButtons.add(findCastComponentById(ResourceTable.Id_slice_badge_radio_button_9));

        tvOffsetX = findCastComponentById(ResourceTable.Id_slice_badge_tv_offset_x);
        seekBarOffsetX = findCastComponentById(ResourceTable.Id_slice_badge_slider_offset_x);
        tvOffsetY = findCastComponentById(ResourceTable.Id_slice_badge_tv_offset_y);
        seekBarOffsetY = findCastComponentById(ResourceTable.Id_slice_badge_slider_offset_y);
        tvPadding = findCastComponentById(ResourceTable.Id_slice_badge_tv_padding);
        seekBarPadding = findCastComponentById(ResourceTable.Id_slice_badge_slider_padding);
        tvNumberSize = findCastComponentById(ResourceTable.Id_slice_badge_text_test_size);
        seekBarNumberSize = findCastComponentById(ResourceTable.Id_slice_badge_slider_test_size);

        etBadgeNumber = findCastComponentById(ResourceTable.Id_slice_badge_tf_badge_number);
        etBadgeText = findCastComponentById(ResourceTable.Id_slice_badge_tf_text);

        tvDragState = findCastComponentById(ResourceTable.Id_slice_badge_text_draggable);

        imgBadgeColor = findCastComponentById(ResourceTable.Id_slice_badge_image_badge_color);
        imgTextColor = findCastComponentById(ResourceTable.Id_slice_badge_image_text_color);
        btnAnimation = findCastComponentById(ResourceTable.Id_slice_badge_animation);
        imgBadgeColor.setClickedListener(this);
        imgTextColor.setClickedListener(this);
        btnAnimation.setClickedListener(this);

        initSwitchCss();
    }

    private StateElement trackElementInit(ShapeElement on, ShapeElement off) {
        StateElement trackElement = new StateElement();
        trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);
        trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);
        return trackElement;
    }

    private StateElement thumbElementInit(ShapeElement on, ShapeElement off) {
        StateElement thumbElement = new StateElement();
        thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);
        thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);
        return thumbElement;
    }

    private void initSwitchCss() {
        ShapeElement elementThumbOn = new ShapeElement();
        elementThumbOn.setShape(ShapeElement.OVAL);
        elementThumbOn.setRgbColor(RgbColor.fromArgbInt(0xFF1E90FF));
        elementThumbOn.setCornerRadius(50);

        // 关闭状态下滑块的样式
        ShapeElement elementThumbOff = new ShapeElement();
        elementThumbOff.setShape(ShapeElement.OVAL);
        elementThumbOff.setRgbColor(RgbColor.fromArgbInt(0xFFFFFFFF));
        elementThumbOff.setCornerRadius(50);

        // 开启状态下轨迹样式
        ShapeElement elementTrackOn = new ShapeElement();
        elementTrackOn.setShape(ShapeElement.RECTANGLE);
        elementTrackOn.setRgbColor(RgbColor.fromArgbInt(0xFF87CEFA));
        elementTrackOn.setCornerRadius(50);

        // 关闭状态下轨迹样式
        ShapeElement elementTrackOff = new ShapeElement();
        elementTrackOff.setShape(ShapeElement.RECTANGLE);
        elementTrackOff.setRgbColor(RgbColor.fromArgbInt(0xFF808080));
        elementTrackOff.setCornerRadius(50);

        switchShadow = findCastComponentById(ResourceTable.Id_slice_badge_switch_shadow);
        switchExact = findCastComponentById(ResourceTable.Id_slice_badge_switch_exactmode);
        switchDraggable = findCastComponentById(ResourceTable.Id_slice_badge_switch_draggable);

        switchShadow.setTrackElement(trackElementInit(elementTrackOn, elementTrackOff));
        switchShadow.setThumbElement(thumbElementInit(elementThumbOn, elementThumbOff));
        switchExact.setTrackElement(trackElementInit(elementTrackOn, elementTrackOff));
        switchExact.setThumbElement(thumbElementInit(elementThumbOn, elementThumbOff));
        switchDraggable.setTrackElement(trackElementInit(elementTrackOn, elementTrackOff));
        switchDraggable.setThumbElement(thumbElementInit(elementThumbOn, elementThumbOff));
    }

    private void setUpView() {
        for (RadioButton rb : radioButtons) {
            rb.setCheckedStateChangedListener(this);
        }

        Slider.ValueChangedListener valueChangedListener = new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean b) {
                for (Badge badge : mBadges) {
                    if (slider == seekBarOffsetX || slider == seekBarOffsetY) {
                        int x = seekBarOffsetX.getProgress();
                        int y = seekBarOffsetY.getProgress();
                        tvOffsetX.setText("GravityOffsetX : " + x);
                        tvOffsetY.setText("GravityOffsetY : " + y);
                        badge.setGravityOffset(x, y);
                    } else if (slider == seekBarPadding) {
                        tvPadding.setText("BadgePadding : " + progress);
                        badge.setBadgePadding(progress);
                    } else if (slider == seekBarNumberSize) {
                        tvNumberSize.setText("TextSize : " + progress);
                        badge.setBadgeTextSize(progress);
                    }
                }
            }

            @Override
            public void onTouchStart(Slider slider) {
            }

            @Override
            public void onTouchEnd(Slider slider) {
            }
        };

        seekBarOffsetX.setValueChangedListener(valueChangedListener);
        seekBarOffsetY.setValueChangedListener(valueChangedListener);
        seekBarPadding.setValueChangedListener(valueChangedListener);
        seekBarNumberSize.setValueChangedListener(valueChangedListener);

        etBadgeNumber.addTextObserver(new MyTextWatcher(etBadgeNumber));
        etBadgeText.addTextObserver(new MyTextWatcher(etBadgeText));

        switchExact.setCheckedStateChangedListener(onCheckedChangeListener);
        switchDraggable.setCheckedStateChangedListener(onCheckedChangeListener);
        switchShadow.setCheckedStateChangedListener(onCheckedChangeListener);
    }

    private void initBadge() {
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#ff9370DB")));
        shapeElement.setCornerRadius(AttrHelper.vp2px(2, getContext()));
        shapeElement.setShape(ShapeElement.RECTANGLE);
        mBadges = new ArrayList<>();
        mBadges.add(new BadgeView(getContext()).bindTarget(text).setBadgeNumber(5));
        mBadges.add(new BadgeView(getContext()).bindTarget(image)
            .setBadgeText("PNG")
            .setBadgeTextColor(Color.BLUE)
            .setBadgeGravity(LayoutAlignment.BOTTOM | LayoutAlignment.END)
            .setBadgeBackgroundColor(new Color(0xff9370DB))
            .setBadgeBackground(shapeElement));
        mBadges.add(new BadgeView(getContext()).bindTarget(button).
            setBadgeText("新")
            .setBadgeTextSize(13)
            .setBadgeBackgroundColor(new Color(0xffffeb3b))
            .setBadgeTextColor(new Color(0xff000000))
            .stroke(new Color(0xff000000), 1));
    }

    private int count = 0;
    private boolean bnChange = false;

    @Override
    public void onCheckedChanged(AbsButton absButton, boolean b) {
        if (bnChange) {
            bnChange = false;
            count = 0;
            return;
        }
        if (absButton.getId() == lastRadioButton.getId()) {
            count++;
            if (count == 1) {
                bnChange = true;
                lastRadioButton.setChecked(true);
                return;
            }
        }
        bnChange = true;
        lastRadioButton.setChecked(false);
        lastRadioButton = absButton;
        for (Badge badge : mBadges) {
            switch (absButton.getId()) {
                case ResourceTable.Id_slice_badge_radio_button_1:
                    badge.setBadgeGravity(LayoutAlignment.START | LayoutAlignment.TOP);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_2:
                    badge.setBadgeGravity(LayoutAlignment.START | LayoutAlignment.BOTTOM);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_3:
                    badge.setBadgeGravity(LayoutAlignment.END | LayoutAlignment.TOP);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_4:
                    badge.setBadgeGravity(LayoutAlignment.END | LayoutAlignment.BOTTOM);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_5:
                    badge.setBadgeGravity(LayoutAlignment.CENTER | LayoutAlignment.TOP);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_6:
                    badge.setBadgeGravity(LayoutAlignment.CENTER | LayoutAlignment.END);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_7:
                    badge.setBadgeGravity(LayoutAlignment.CENTER | LayoutAlignment.BOTTOM);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_8:
                    badge.setBadgeGravity(LayoutAlignment.CENTER | LayoutAlignment.START);
                    break;
                case ResourceTable.Id_slice_badge_radio_button_9:
                    badge.setBadgeGravity(LayoutAlignment.CENTER);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_slice_badge_image_badge_color:
                new SelectorColorDialog(getContext(), color -> {
                    imgBadgeColor.setBackground(ColorUtils.getColorShapeElement(color));
                    for (Badge badge : mBadges) {
                        badge.setBadgeBackgroundColor(new Color(color));
                    }
                }).show();
                break;
            case ResourceTable.Id_slice_badge_image_text_color:
                new SelectorColorDialog(getContext(), color -> {
                    imgTextColor.setBackground(ColorUtils.getColorShapeElement(color));
                    for (Badge badge : mBadges) {
                        badge.setBadgeTextColor(new Color(color));
                    }
                }).show();
                break;
            case ResourceTable.Id_slice_badge_animation:
                for (Badge badge : mBadges) {
                    badge.hide(true);
                }
                break;
        }
    }

    class MyTextWatcher implements Text.TextObserver {
        private TextField editText;

        public MyTextWatcher(TextField editText) {
            this.editText = editText;
        }

        @Override
        public void onTextUpdated(String s, int i, int i1, int i2) {
            try {
                for (Badge badge : mBadges) {
                    if (editText == etBadgeNumber) {
                        int num = TextUtils.isEmpty(s) ? 0 : Integer.parseInt(s.toString());
                        badge.setBadgeNumber(num);
                    } else if (editText == etBadgeText) {
                        badge.setBadgeText(s.toString());
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
